package com.github.chirspan.xaas.exception;

import com.github.chirspan.xaas.core.rest.RestResult;
import com.github.chirspan.xaas.core.rest.RestResultStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * *******description*******
 * 全局Rest接口异常处理
 * *************************
 *
 * @author chenpan
 * @date 2020/5/15 12:00
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionAdvice {

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({HttpMessageNotReadableException.class,
            MissingServletRequestParameterException.class,
            BindException.class,
            ServletRequestBindingException.class,
            MethodArgumentNotValidException.class
    })
    public RestResult handleHttpMessageNotReadableException(Exception e) {
        if (e instanceof BindException) {
            return new RestResult(RestResultStatus.BAD_REQUEST, ((BindException) e).getAllErrors().get(0).getDefaultMessage(), null);
        }
        return new RestResult(RestResultStatus.BAD_REQUEST, e.getMessage(), null);
    }

    /**
     * 405 - Method Not Allowed
     * 带有@ResponseStatus注解的异常类会被ResponseStatusExceptionResolver 解析
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public RestResult handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        return new RestResult(RestResultStatus.METHOD_NOT_ALLOWED);
    }

    /**
     * 其他全局异常在此捕获
     *
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public RestResult handleException(Exception e) {
        return GlobalExceptionHandler.handleRestError(e);
    }

}
